package com.newfiber.system.service.impl;

import com.newfiber.common.core.constant.CacheConstants;
import com.newfiber.common.core.constant.Constants;
import com.newfiber.common.core.exception.ServiceException;
import com.newfiber.common.redis.service.RedisService;
import com.newfiber.common.security.utils.SecurityUtils;
import com.newfiber.system.api.domain.SysUser;
import com.newfiber.system.api.enums.ESystemRedisKey;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 登录密码方法
 * 
 * @author newfiber
 */
@Component
public class SysPasswordService{
    @Autowired
    private RedisService redisService;

    private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;

    private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;

    @Autowired
    private SysRecordLogService recordLogService;

    public void validate(SysUser user, String password){
        String username = user.getUserName();

        Integer retryCount = redisService.getCacheObject(ESystemRedisKey.PwdErrCnt, username);

        if (retryCount == null){
            retryCount = 0;
        }

        if (retryCount >= Integer.valueOf(maxRetryCount).intValue()){
            String errMsg = String.format("密码输入错误%s次，帐户锁定%s分钟", maxRetryCount, lockTime);
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL,errMsg);
            throw new ServiceException(errMsg);
        }

        if (!matches(user, password)){
            retryCount = retryCount + 1;
            recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, String
	            .format("密码输入错误%s次", retryCount));
            redisService.setCacheObject(ESystemRedisKey.PwdErrCnt, username, retryCount, lockTime, TimeUnit.MINUTES);
            throw new ServiceException("用户不存在/密码错误");
        }
        else{
            clearLoginRecordCache(username);
        }
    }

    public boolean matches(SysUser user, String rawPassword){
        return SecurityUtils.matchesPassword(rawPassword, user.getPassword());
    }

    public void clearLoginRecordCache(String loginName){
        if (redisService.hasKey(ESystemRedisKey.PwdErrCnt, loginName)){
            redisService.deleteObject(ESystemRedisKey.PwdErrCnt, loginName);
        }
    }
}
